This notebook performs Exploratory Data Analysis on the motor vehicle crashes data aggregated with the ACS data

LOAD DATA

df <- read_csv("../data/processed/acs_mvc_combined_2018_2023.csv")
glimpse(df)
Rows: 13,984
Columns: 50
$ geoid                   <dbl> 3.6005e+10, 3.6005e+10, 3.6005e+10, 3.6005e…
$ year                    <dbl> 2018, 2019, 2020, 2021, 2022, 2023, 2018, 2…
$ total_population        <dbl> 47900.000, 46630.000, 44881.000, 45523.000,…
$ pct_male_population     <dbl> 13.576200, 13.607120, 13.691763, 13.568965,…
$ pct_female_population   <dbl> 1.2045929, 1.1130174, 1.0137920, 1.0631988,…
$ pct_white_population    <dbl> 3.7014614, 4.7887626, 5.7039727, 5.8871340,…
$ pct_black_population    <dbl> 8.849687, 8.200729, 7.666941, 7.187576, 6.7…
$ pct_asian_population    <dbl> 0.26096033, 0.38816213, 0.38100755, 0.38881…
$ pct_hispanic_population <dbl> 4.862213, 5.161913, 5.158085, 4.758034, 3.8…
$ pct_foreign_born        <dbl> 2.206681, 2.365430, 2.319467, 2.220855, 1.9…
$ pct_age_under_18        <dbl> 0.3569937, 0.2208878, 0.2161271, 0.2152758,…
$ pct_age_18_34           <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_age_35_64           <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_age_65_plus         <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ median_income           <dbl> 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 5…
$ pct_income_under_25k    <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_income_25k_75k      <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_income_75k_plus     <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_below_poverty       <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_above_poverty       <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ poverty_rate            <dbl> NA, NA, NA, NA, NA, NA, 22.633201, 22.44042…
$ median_gross_rent       <dbl> 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0…
$ pct_owner_occupied      <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_renter_occupied     <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_no_vehicle          <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_one_vehicle         <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_two_plus_vehicles   <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_less_than_hs        <dbl> 6.3924843, 6.0261634, 5.7017446, 5.6608747,…
$ pct_hs_diploma          <dbl> 2.0229645, 2.7364358, 3.0547448, 3.4619862,…
$ pct_some_college        <dbl> 1.2526096, 1.1237401, 1.0405294, 0.9797245,…
$ pct_associates_degree   <dbl> 0.1691023, 0.1737079, 0.2339520, 0.2723898,…
$ pct_bachelors_degree    <dbl> 0.14822547, 0.15440703, 0.18938972, 0.23724…
$ pct_graduate_degree     <dbl> 0.01670146, 0.01930088, 0.04233417, 0.05272…
$ pct_in_labor_force      <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_employed            <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_unemployed          <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_not_in_labor_force  <dbl> 14.780793, 14.720137, 14.705555, 14.632164,…
$ unemployment_rate       <dbl> NA, NA, NA, NA, NA, NA, 15.750133, 13.47874…
$ pct_commute_short       <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_commute_medium      <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_commute_long        <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_drive_alone         <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_carpool             <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_public_transit      <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_walk                <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_bike                <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_work_from_home      <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ crash_rate_per_1000     <dbl> 0.04175365, 0.08578169, 0.00000000, 0.00000…
$ injury_rate_per_1000    <dbl> 0.02087683, 0.04289084, 0.00000000, 0.00000…
$ fatality_rate_per_1000  <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…

CONVERT DATA TYPES

df <- df %>%
  mutate(
    geoid = as.character(geoid),
    year = as.integer(year),
    total_population = as.integer(total_population)
  )
glimpse(df)
Rows: 13,984
Columns: 50
$ geoid                   <chr> "36005000100", "36005000100", "36005000100"…
$ year                    <int> 2018, 2019, 2020, 2021, 2022, 2023, 2018, 2…
$ total_population        <int> 47900, 46630, 44881, 45523, 30541, 24345, 5…
$ pct_male_population     <dbl> 13.576200, 13.607120, 13.691763, 13.568965,…
$ pct_female_population   <dbl> 1.2045929, 1.1130174, 1.0137920, 1.0631988,…
$ pct_white_population    <dbl> 3.7014614, 4.7887626, 5.7039727, 5.8871340,…
$ pct_black_population    <dbl> 8.849687, 8.200729, 7.666941, 7.187576, 6.7…
$ pct_asian_population    <dbl> 0.26096033, 0.38816213, 0.38100755, 0.38881…
$ pct_hispanic_population <dbl> 4.862213, 5.161913, 5.158085, 4.758034, 3.8…
$ pct_foreign_born        <dbl> 2.206681, 2.365430, 2.319467, 2.220855, 1.9…
$ pct_age_under_18        <dbl> 0.3569937, 0.2208878, 0.2161271, 0.2152758,…
$ pct_age_18_34           <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_age_35_64           <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_age_65_plus         <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ median_income           <dbl> 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 5…
$ pct_income_under_25k    <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_income_25k_75k      <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_income_75k_plus     <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_below_poverty       <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_above_poverty       <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ poverty_rate            <dbl> NA, NA, NA, NA, NA, NA, 22.633201, 22.44042…
$ median_gross_rent       <dbl> 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0…
$ pct_owner_occupied      <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_renter_occupied     <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_no_vehicle          <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_one_vehicle         <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_two_plus_vehicles   <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_less_than_hs        <dbl> 6.3924843, 6.0261634, 5.7017446, 5.6608747,…
$ pct_hs_diploma          <dbl> 2.0229645, 2.7364358, 3.0547448, 3.4619862,…
$ pct_some_college        <dbl> 1.2526096, 1.1237401, 1.0405294, 0.9797245,…
$ pct_associates_degree   <dbl> 0.1691023, 0.1737079, 0.2339520, 0.2723898,…
$ pct_bachelors_degree    <dbl> 0.14822547, 0.15440703, 0.18938972, 0.23724…
$ pct_graduate_degree     <dbl> 0.01670146, 0.01930088, 0.04233417, 0.05272…
$ pct_in_labor_force      <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_employed            <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_unemployed          <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_not_in_labor_force  <dbl> 14.780793, 14.720137, 14.705555, 14.632164,…
$ unemployment_rate       <dbl> NA, NA, NA, NA, NA, NA, 15.750133, 13.47874…
$ pct_commute_short       <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_commute_medium      <dbl> 0.0000000, 0.0000000, 0.0000000, 0.0000000,…
$ pct_commute_long        <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_drive_alone         <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_carpool             <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_public_transit      <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
$ pct_walk                <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_bike                <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ pct_work_from_home      <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…
$ crash_rate_per_1000     <dbl> 0.04175365, 0.08578169, 0.00000000, 0.00000…
$ injury_rate_per_1000    <dbl> 0.02087683, 0.04289084, 0.00000000, 0.00000…
$ fatality_rate_per_1000  <dbl> 0.00000000, 0.00000000, 0.00000000, 0.00000…

DATA QUALITY CHECKS

# Visualize missingness
vis_miss(df)


# Count NA values per column
colSums(is.na(df))
                  geoid                    year        total_population 
                      0                       0                       0 
    pct_male_population   pct_female_population    pct_white_population 
                    426                     426                     426 
   pct_black_population    pct_asian_population pct_hispanic_population 
                    426                     426                     426 
       pct_foreign_born        pct_age_under_18           pct_age_18_34 
                    426                     426                     426 
          pct_age_35_64         pct_age_65_plus           median_income 
                    426                     426                       0 
   pct_income_under_25k      pct_income_25k_75k     pct_income_75k_plus 
                    426                     426                     426 
      pct_below_poverty       pct_above_poverty            poverty_rate 
                    426                     426                     455 
      median_gross_rent      pct_owner_occupied     pct_renter_occupied 
                      0                     426                     426 
         pct_no_vehicle         pct_one_vehicle   pct_two_plus_vehicles 
                    426                     426                     426 
       pct_less_than_hs          pct_hs_diploma        pct_some_college 
                    426                     426                     426 
  pct_associates_degree    pct_bachelors_degree     pct_graduate_degree 
                    426                     426                     426 
     pct_in_labor_force            pct_employed          pct_unemployed 
                    426                     426                     426 
 pct_not_in_labor_force       unemployment_rate       pct_commute_short 
                    426                     464                     426 
     pct_commute_medium        pct_commute_long         pct_drive_alone 
                    426                     426                     426 
            pct_carpool      pct_public_transit                pct_walk 
                    426                     426                     426 
               pct_bike      pct_work_from_home     crash_rate_per_1000 
                    426                     426                     426 
   injury_rate_per_1000  fatality_rate_per_1000 
                    426                     426 

Identify and remove 426 rows with extensive missingness

df$na_rate <- rowMeans(is.na(df))

# Filter out rows with high missingness
df <- df %>%
    filter(rowMeans(is.na(.)) <= 0.05)

# Drop 29 rows with poverty_rate NA and/or 38 unemployment_rate NA values
df <- df %>%
    drop_na(c(unemployment_rate, poverty_rate))

# Drop na_rate column
df <- df %>% select(-na_rate)

Second quality check

# Visualize missingness
vis_miss(df)

NO NA values!

Winsorization of extreme values

replace_top_99_with_median <- function(x) {
  # Ensure numeric
  if (!is.numeric(x)) stop("Column must be numeric.")
  
  # Calculate the 99th percentile and median
  upper_threshold <- quantile(x, 0.99, na.rm = TRUE)
  median_val <- median(x, na.rm = TRUE)
  
  # Replace values above the 99th percentile with the median
  x[x > upper_threshold] <- median_val
  return(x)
}

per_1000_vars <- grep("per_1000", names(df), value = TRUE)
df[per_1000_vars] <- lapply(df[per_1000_vars], replace_top_99_with_median)

Univariate Analysis

GROUP CORRELATED SOCIO-ECONOMIC VARIABLES

numeric_vars <- sapply(df, is.numeric)
cor_matrix <- cor(df[ , numeric_vars], 
                  use = "pairwise.complete.obs")

# Identify columns to drop (to reduce multicollinearity)
high_corr <- caret::findCorrelation(cor_matrix, cutoff = 0.8)
colnames(cor_matrix)[high_corr]
[1] "pct_income_75k_plus"   "poverty_rate"          "pct_below_poverty"    
[4] "pct_employed"          "pct_no_vehicle"        "pct_drive_alone"      
[7] "unemployment_rate"     "pct_female_population"
# Open a PNG device
png("../report/plots/pairwise_correlation_matrix.png", width = 1200, height = 1000, res = 300)

# Draw the plot
corrplot(cor_matrix, method = "color", type = "upper", tl.cex = 0.5)

# Close the device
dev.off()
null device 
          1 

DROP REDUNDANT VARIABLES

df <- df %>%
    select(-c(poverty_rate,
              pct_below_poverty,
              pct_above_poverty,
              pct_employed,
              pct_unemployed,
              pct_drive_alone))

ADD BOROUGHS

df <- df %>%
  mutate(
    borough = case_when(
      substr(geoid, 1, 5) == "36005" ~ "Bronx",
      substr(geoid, 1, 5) == "36047" ~ "Brooklyn",
      substr(geoid, 1, 5) == "36061" ~ "Manhattan",
      substr(geoid, 1, 5) == "36081" ~ "Queens",
      substr(geoid, 1, 5) == "36085" ~ "Staten Island",
      TRUE ~ "Unknown"
    )
  )

Export clean data

saveRDS(df, "../data/models/social-risk-crash-rate-data.rds")
LS0tCnRpdGxlOiAiMDEtRURBIFIgTm90ZWJvb2siCmF1dGhvcjogIkFKIFN0cmF1bWFuLVNjb3R0IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClRoaXMgbm90ZWJvb2sgcGVyZm9ybXMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyBvbiB0aGUgbW90b3IgdmVoaWNsZSBjcmFzaGVzIGRhdGEgYWdncmVnYXRlZCB3aXRoIHRoZSBBQ1MgZGF0YQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KEdHYWxseSkKbGlicmFyeShjb3JycGxvdCkKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KG5hbmlhcikKbGlicmFyeSh0bWFwKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShEZXNjVG9vbHMpCmBgYAoKIyMgTE9BRCBEQVRBCgpgYGB7ciBsb2FkLWRhdGF9CmRmIDwtIHJlYWRfY3N2KCIuLi9kYXRhL3Byb2Nlc3NlZC9hY3NfbXZjX2NvbWJpbmVkXzIwMThfMjAyMy5jc3YiKQpnbGltcHNlKGRmKQpgYGAKCiMjIENPTlZFUlQgREFUQSBUWVBFUwoKYGBge3IgY29udmVydC1kYXRhLXR5cGVzfQpkZiA8LSBkZiAlPiUKICBtdXRhdGUoCiAgICBnZW9pZCA9IGFzLmNoYXJhY3RlcihnZW9pZCksCiAgICB5ZWFyID0gYXMuaW50ZWdlcih5ZWFyKSwKICAgIHRvdGFsX3BvcHVsYXRpb24gPSBhcy5pbnRlZ2VyKHRvdGFsX3BvcHVsYXRpb24pCiAgKQpnbGltcHNlKGRmKQpgYGAKCiMjIERBVEEgUVVBTElUWSBDSEVDS1MKCmBgYHtyIHF1YWxpdHktY2hlY2tzfQojIFZpc3VhbGl6ZSBtaXNzaW5nbmVzcwp2aXNfbWlzcyhkZikKCiMgQ291bnQgTkEgdmFsdWVzIHBlciBjb2x1bW4KY29sU3Vtcyhpcy5uYShkZikpCmBgYApJZGVudGlmeSBhbmQgcmVtb3ZlIDQyNiByb3dzIHdpdGggZXh0ZW5zaXZlIG1pc3NpbmduZXNzCgpgYGB7ciByb3dzLXdpdGgtTkFzfQpkZiRuYV9yYXRlIDwtIHJvd01lYW5zKGlzLm5hKGRmKSkKCiMgRmlsdGVyIG91dCByb3dzIHdpdGggaGlnaCBtaXNzaW5nbmVzcwpkZiA8LSBkZiAlPiUKICAgIGZpbHRlcihyb3dNZWFucyhpcy5uYSguKSkgPD0gMC4wNSkKCiMgRHJvcCAyOSByb3dzIHdpdGggcG92ZXJ0eV9yYXRlIE5BIGFuZC9vciAzOCB1bmVtcGxveW1lbnRfcmF0ZSBOQSB2YWx1ZXMKZGYgPC0gZGYgJT4lCiAgICBkcm9wX25hKGModW5lbXBsb3ltZW50X3JhdGUsIHBvdmVydHlfcmF0ZSkpCgojIERyb3AgbmFfcmF0ZSBjb2x1bW4KZGYgPC0gZGYgJT4lIHNlbGVjdCgtbmFfcmF0ZSkKYGBgCiAKU2Vjb25kIHF1YWxpdHkgY2hlY2sKIApgYGB7ciBxdWFsaXR5LWNoZWNrLWFnYWlufQojIFZpc3VhbGl6ZSBtaXNzaW5nbmVzcwp2aXNfbWlzcyhkZikKYGBgCk5PIE5BIHZhbHVlcyEKCgojIyBXaW5zb3JpemF0aW9uIG9mIGV4dHJlbWUgdmFsdWVzCgpgYGB7ciB3aW5zb3JpemUtdmFyaWFibGVzfQpyZXBsYWNlX3RvcF85OV93aXRoX21lZGlhbiA8LSBmdW5jdGlvbih4KSB7CiAgIyBFbnN1cmUgbnVtZXJpYwogIGlmICghaXMubnVtZXJpYyh4KSkgc3RvcCgiQ29sdW1uIG11c3QgYmUgbnVtZXJpYy4iKQogIAogICMgQ2FsY3VsYXRlIHRoZSA5OXRoIHBlcmNlbnRpbGUgYW5kIG1lZGlhbgogIHVwcGVyX3RocmVzaG9sZCA8LSBxdWFudGlsZSh4LCAwLjk5LCBuYS5ybSA9IFRSVUUpCiAgbWVkaWFuX3ZhbCA8LSBtZWRpYW4oeCwgbmEucm0gPSBUUlVFKQogIAogICMgUmVwbGFjZSB2YWx1ZXMgYWJvdmUgdGhlIDk5dGggcGVyY2VudGlsZSB3aXRoIHRoZSBtZWRpYW4KICB4W3ggPiB1cHBlcl90aHJlc2hvbGRdIDwtIG1lZGlhbl92YWwKICByZXR1cm4oeCkKfQoKcGVyXzEwMDBfdmFycyA8LSBncmVwKCJwZXJfMTAwMCIsIG5hbWVzKGRmKSwgdmFsdWUgPSBUUlVFKQpkZltwZXJfMTAwMF92YXJzXSA8LSBsYXBwbHkoZGZbcGVyXzEwMDBfdmFyc10sIHJlcGxhY2VfdG9wXzk5X3dpdGhfbWVkaWFuKQpgYGAKCiMjIFVuaXZhcmlhdGUgQW5hbHlzaXMKCmBgYHtyIHVuaXZhcmlhdGUtYW5hbHlzaXMsIGVjaG89RkFMU0V9CiMgSWRlbnRpZnkgbnVtZXJpYyBjb2x1bW5zCm51bWVyaWNfdmFycyA8LSBkZiAlPiUgCiAgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKSAlPiUgCiAgICBzZWxlY3QoLXllYXIpICU+JQogIG5hbWVzKCkKCiMgQ3JlYXRlIGhpc3RvZ3JhbXMgYW5kIGJveHBsb3RzIGZvciBlYWNoIG51bWVyaWMgdmFyaWFibGUKZm9yICh2YXIgaW4gbnVtZXJpY192YXJzKSB7CiAgIyBIaXN0b2dyYW0KICBwcmludCgKICAgIGdncGxvdChkZiwgYWVzX3N0cmluZyh4ID0gdmFyKSkgKwogICAgICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMzAsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArCiAgICAgIGxhYnModGl0bGUgPSBwYXN0ZSgiSGlzdG9ncmFtIG9mIiwgdmFyKSwgeCA9IHZhciwgeSA9ICJDb3VudCIpICsKICAgICAgdGhlbWVfbWluaW1hbCgpCiAgKQogIAogICMgQm94cGxvdAogIHByaW50KAogICAgZ2dwbG90KGRmLCBhZXNfc3RyaW5nKHggPSAiJyciLCB5ID0gdmFyKSkgKwogICAgICBnZW9tX2JveHBsb3QoZmlsbCA9ICJ0b21hdG8iLCBjb2xvciA9ICJibGFjayIpICsKICAgICAgbGFicyh0aXRsZSA9IHBhc3RlKCJCb3hwbG90IG9mIiwgdmFyKSwgeCA9ICIiLCB5ID0gdmFyKSArCiAgICAgIHRoZW1lX21pbmltYWwoKQogICkKfQpgYGAKCiMjIEdST1VQIENPUlJFTEFURUQgU09DSU8tRUNPTk9NSUMgVkFSSUFCTEVTCgpgYGB7ciBncm91cC12YXJzfQpudW1lcmljX3ZhcnMgPC0gc2FwcGx5KGRmLCBpcy5udW1lcmljKQpjb3JfbWF0cml4IDwtIGNvcihkZlsgLCBudW1lcmljX3ZhcnNdLCAKICAgICAgICAgICAgICAgICAgdXNlID0gInBhaXJ3aXNlLmNvbXBsZXRlLm9icyIpCgojIElkZW50aWZ5IGNvbHVtbnMgdG8gZHJvcCAodG8gcmVkdWNlIG11bHRpY29sbGluZWFyaXR5KQpoaWdoX2NvcnIgPC0gY2FyZXQ6OmZpbmRDb3JyZWxhdGlvbihjb3JfbWF0cml4LCBjdXRvZmYgPSAwLjgpCmNvbG5hbWVzKGNvcl9tYXRyaXgpW2hpZ2hfY29ycl0KCiMgT3BlbiBhIFBORyBkZXZpY2UKcG5nKCIuLi9yZXBvcnQvcGxvdHMvcGFpcndpc2VfY29ycmVsYXRpb25fbWF0cml4LnBuZyIsIHdpZHRoID0gMTIwMCwgaGVpZ2h0ID0gMTAwMCwgcmVzID0gMzAwKQoKIyBEcmF3IHRoZSBwbG90CmNvcnJwbG90KGNvcl9tYXRyaXgsIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCB0bC5jZXggPSAwLjUpCgojIENsb3NlIHRoZSBkZXZpY2UKZGV2Lm9mZigpCmBgYAojIyBEUk9QIFJFRFVOREFOVCBWQVJJQUJMRVMKCmBgYHtyIGRyb3AtcmVkdW5kYW50fQpkZiA8LSBkZiAlPiUKICAgIHNlbGVjdCgtYyhwb3ZlcnR5X3JhdGUsCiAgICAgICAgICAgICAgcGN0X2Fib3ZlX3BvdmVydHksCiAgICAgICAgICAgICAgcGN0X2VtcGxveWVkLAogICAgICAgICAgICAgIHBjdF91bmVtcGxveWVkLAogICAgICAgICAgICAgIHBjdF9kcml2ZV9hbG9uZSkpCmBgYAoKIyMgQUREIEJPUk9VR0hTCgpgYGB7ciBhZGQtYm9yb3VnaHN9CmRmIDwtIGRmICU+JQogIG11dGF0ZSgKICAgIGJvcm91Z2ggPSBjYXNlX3doZW4oCiAgICAgIHN1YnN0cihnZW9pZCwgMSwgNSkgPT0gIjM2MDA1IiB+ICJCcm9ueCIsCiAgICAgIHN1YnN0cihnZW9pZCwgMSwgNSkgPT0gIjM2MDQ3IiB+ICJCcm9va2x5biIsCiAgICAgIHN1YnN0cihnZW9pZCwgMSwgNSkgPT0gIjM2MDYxIiB+ICJNYW5oYXR0YW4iLAogICAgICBzdWJzdHIoZ2VvaWQsIDEsIDUpID09ICIzNjA4MSIgfiAiUXVlZW5zIiwKICAgICAgc3Vic3RyKGdlb2lkLCAxLCA1KSA9PSAiMzYwODUiIH4gIlN0YXRlbiBJc2xhbmQiLAogICAgICBUUlVFIH4gIlVua25vd24iCiAgICApCiAgKQoKYGBgCgojIyBFeHBvcnQgY2xlYW4gZGF0YQoKYGBge3IgZXhwb3J0fQpzYXZlUkRTKGRmLCAiLi4vZGF0YS9tb2RlbHMvc29jaWFsLXJpc2stY3Jhc2gtcmF0ZS1kYXRhLnJkcyIpCmBgYA==